package org.ht.util;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Classe que reúne métodos estáticos variados para formatação de strings.
 * @author Issao Hanaoka Junior
 */
public class Formatador {

    /**
     * Extrai caracteres não-dígitos de uma String
     * @param str
     * @return String de dígitos
     */
    public static String extraiNaoDigitos(String str) {
        if (str == null) {
            str = "";
        }
        List<String> strList = new ArrayList();

        for (int i = 0; i < str.length(); i++) {
            if (Character.isDigit(str.charAt(i))) {
                strList.add(String.valueOf(str.charAt(i)));
            }
        }

        StringBuilder out = new StringBuilder();
        for (Object o : strList) {
            out.append(o.toString());
        }
        return out.toString();
    }

    /**
     * Extrai caracteres inválidos customizados de uma String, filtrando-a
     * @param str String a ser filtrada 
     * @param invalidos String de caracteres inválidos. 
     * Por exemplo, a string "#e-! @" considera que cada caractere nela contido
     * é inválido. Assim, a string "abc@ de!" seria filtrada para "abcde"
     * @return String filtrada.
     */
    public static String extraiCaracteresInvalidos(String str, String invalidos) {
        if (str == null) {
            str = "";
        }
        if (invalidos == null) {
            invalidos = "";
        }
        StringBuilder strBuilder = new StringBuilder();
        List strList = new ArrayList();

        for (int i = 0; i < str.length(); i++) {
            if (!invalidos.contains(str.substring(i, i + 1))) {
                strList.add(str.substring(i, i + 1));
            }
        }

        for (Object object : strList) {
            strBuilder.append(object);
        }

        return strBuilder.toString();
    }
    
    /**
     * Aceita dígitos, letras e caracteres definidos pelo usuário. Extrai da
     * string demais caracteres.
     * @param str
     * @param permitidos
     * @return string filtrada
     */
    public static String filtraCaracteres(String str, String permitidos) {
        if (str == null) {
            str = "";
        }
        if (permitidos == null) {
            permitidos = "";
        }
        StringBuilder strBuilder = new StringBuilder();
        List strList = new ArrayList();

        for (int i = 0; i < str.length(); i++) {
            if (Character.isLetterOrDigit(str.charAt(i)) ||
                    permitidos.contains(str.substring(i, i + 1))) {
                strList.add(str.substring(i, i + 1));
            }
        }

        for (Object object : strList) {
            strBuilder.append(object);
        }

        return strBuilder.toString();
    }

    /**
     * processa uma string, e retorna a mesma String capitulada. Em adição,
     * retira espaços vazios no início, no final e espaços múltiplos.
     * Especialmente útil para capitulação de nomes.
     * Por exemplo:
     * Entrada: "  aMaraL    NETO De souza E sanTOS  "
     * Saída: "Amaral Neto de Souza e Santos"
     * 
     * Caso a entrada seja um valor null, a saída será uma String vazia ""
     * @param str
     * @return uma String capitulada
     */
    public static String capitula(String str) {
        if (str == null) {
            str = "";
        }
        StringBuilder strBuilder = new StringBuilder();
        List<String> palavrasList = Arrays.asList(str.toLowerCase().split("\\s+"));
        List ignorarList = new ArrayList();
        ignorarList.add("da");
        ignorarList.add("das");
        ignorarList.add("de");
        ignorarList.add("des");
        ignorarList.add("do");
        ignorarList.add("dos");

        for (String palavra : palavrasList) {
            if (!ignorarList.contains(palavra) && palavra.length() > 1) {
                strBuilder.append(palavra.substring(0, 1).toUpperCase()).append(palavra.substring(1)).append(" ");
            } else {
                strBuilder.append(palavra).append(" ");
            }
        }
        return strBuilder.toString().trim();
    }

    /**
     * Método ainda não implementado.
     * @param str
     * @return nao suportado
     */
    public static String utf8paraIso88591(String str) {
        // a implementar
        throw new UnsupportedOperationException("Método ainda não implementado.");
    }

    /**
     * processa uma String de telefone, em qualquer formato, produzindo uma
     * string no formato: "99 9999 9999"
     * @param str
     * @return string de telefone no formato "99 9999 9999"
     */
    public static String telefoneRpc(String str) {
        if (str == null) {
            str = "";
        }
        StringBuilder tel = new StringBuilder(extraiNaoDigitos(str));

        if (tel != null && tel.length() == 10) {
            tel.insert(2, " ");
            tel.insert(7, " ");
            str = tel.toString();
        }
        return str;
    }

    public static String converteParaMoeda(Double valor) {
        if (valor != null) {
            NumberFormat formatter = new DecimalFormat("#.00");

            return formatter.format(valor);
        }
        return null;
    }

    public static Double longParaDoubleMoeda(Long valorLong) {
        String str = String.valueOf(valorLong);

        if(str.length() == 1) {
            str = "00" + str;
        }
        
        if(str.length() == 2) {
            str = "0" + str;
        }
        
        if (str.length() > 2) {
            String valorInteiro = str.substring(0, str.length() - 2);
            String centavos = str.substring(str.length() - 2, str.length());
            StringBuilder strBuilder = new StringBuilder(valorInteiro).append(".").append(centavos);
            str = strBuilder.toString();
        } 

        return Double.parseDouble(str);
    }
}
